From a5ba5d3f2bffb5d62ab0a2fe9d0df4ae42cb0e1e Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 10 Feb 2004 14:38:31 +0000 Subject: [PATCH] bitkeeper revision 1.716 (4028ece7eoQBod_jQtuJv99FK7huwA) xc_netbsd_build.c, xc_vd_tool.py, xc_dom_control.py, README, VBD-HOWTO.txt: More fixes applied from Xen v1.2. --- docs/VBD-HOWTO.txt | 10 +-- tools/examples/README | 2 +- tools/examples/xc_dom_control.py | 16 ++-- tools/examples/xc_vd_tool.py | 12 ++- tools/xc/lib/xc_netbsd_build.c | 144 +++++++++++++++++++------------ 5 files changed, 108 insertions(+), 76 deletions(-) diff --git a/docs/VBD-HOWTO.txt b/docs/VBD-HOWTO.txt index b1a4f2dd3f..b1d12a5f96 100644 --- a/docs/VBD-HOWTO.txt +++ b/docs/VBD-HOWTO.txt @@ -225,7 +225,7 @@ vbd_remove dom dev - Removes the VBD associated with a specified device These scripts are most useful when populating VDs. VDs can't be populated directly, since they don't correspond to real devices. Using: - xc_dom_control.py vbd_add vd:your_vd_id /dev/whatever 0 w + xc_dom_control.py vbd_add 0 vd:your_vd_id /dev/whatever w You can make a virtual disk available to DOM0. Sensible devices to map VDs to in DOM0 are the /dev/xvd* nodes, since that makes it obvious that they are Xen @@ -234,7 +234,7 @@ virtual devices that don't correspond to real physical devices. You can then format, mount and populate the VD through the nominated device node. When you've finished, use: - xc_dom_control.py vbd_remove /dev/whatever 0 + xc_dom_control.py vbd_remove 0 /dev/whatever To revoke DOM0's access to it. It's then ready for use in a guest domain. @@ -269,7 +269,7 @@ access virtual disks to a running domain (described above). Specify the device as "phy:device", where device is the name of the device as seen from domain 0, or from normal Linux without Xen. For instance: -> xc_dom_control.py vbd_add phy:hdc /dev/whatever 2 r +> xc_dom_control.py vbd_add 2 phy:hdc /dev/whatever r Will grant domain 2 read-only access to the device /dev/hdc (as seen from Dom0 / normal Linux running on the same machine - i.e. the master drive on the @@ -355,7 +355,7 @@ standard Linux root filesystem. You'll need to temporarily add the VD to DOM0 in order to do this. To give DOM0 r/w access to the VD, use the following command line, substituting the ID you got earlier. -> xc_dom_control.py vbd_add vd: /dev/xvda 0 w +> xc_dom_control.py vbd_add 0 vd: /dev/xvda w This attaches the VD to the device /dev/xvda in domain zero, with read / write privileges - you can use other devices nodes if you choose too. @@ -368,7 +368,7 @@ You should now remove the VD from DOM0. This will prevent you accidentally changing it in DOM0, whilst the guest domain is using it (which could cause filesystem corruption, and confuse Linux). -> xc_dom_control.py vbd_remove /dev/xvda 0 +> xc_dom_control.py vbd_remove 0 /dev/xvda It should now be possible to boot a guest domain from the VD. To do this, you should specify the the VD's details in some way so that xc_dom_create.py will diff --git a/tools/examples/README b/tools/examples/README index 4d06bd9d62..82041d7ad1 100644 --- a/tools/examples/README +++ b/tools/examples/README @@ -35,7 +35,7 @@ xc_dom_control.py vif_setsched [dom] [vif] [bytes] [usecs] -- rate limit vif bandwidth vif_getsched [dom] [vif] -- print vif's scheduling parameters vbd_add [dom] [uname] [dev] [mode] -- make disk/partition uname available to - domain as dev e.g. 'vbd_add phy:sda3 hda1 rw' + domain as dev e.g. 'vbd_add 2 phy:sda3 hda1 w' vbd_remove [dom] [dev] -- remove disk or partition attached as 'dev' diff --git a/tools/examples/xc_dom_control.py b/tools/examples/xc_dom_control.py index bac31cdd21..1f7424d092 100755 --- a/tools/examples/xc_dom_control.py +++ b/tools/examples/xc_dom_control.py @@ -28,7 +28,7 @@ Usage: %s [command] vif_setsched [dom] [vif] [bytes] [usecs] -- rate limit vif bandwidth vif_getsched [dom] [vif] -- print vif's scheduling parameters vbd_add [dom] [uname] [dev] [mode] -- make disk/partition uname available to - domain as dev e.g. 'vbd_add phy:sda3 hda1 rw' + domain as dev e.g. 'vbd_add 2 phy:sda3 hda1 w' vbd_remove [dom] [dev] -- remove disk or partition attached as 'dev' """ % sys.argv[0] @@ -119,14 +119,12 @@ elif cmd == 'unwatch': os.kill(pid, signal.SIGTERM) elif cmd == 'listvbds': - vbdInfo = xc.vbd_probe() - for vbd in vbdInfo: - print 'dom:' + str(vbd['dom']) - del vbd['dom'] - print '-----' - for field in vbd: - print field + ': ' + str(vbd[field]) - print '\n' + print 'Dom Dev Perm Size(MB)' + + for vbd in xc.vbd_probe(): + vbd['size_mb'] = vbd['nr_sectors'] / 2048 + vbd['perm'] = (vbd['writeable'] and 'w') or 'r' + print '%(dom)-4d %(vbd)04x %(perm)-1s %(size_mb)d' % vbd elif cmd == 'suspend': if len(sys.argv) < 4: diff --git a/tools/examples/xc_vd_tool.py b/tools/examples/xc_vd_tool.py index 787bcff0fa..95e316c741 100755 --- a/tools/examples/xc_vd_tool.py +++ b/tools/examples/xc_vd_tool.py @@ -110,19 +110,17 @@ elif cmd == 'setexpiry': print "Refreshing a virtual disk" print "Id: " + id - print "Expiry time (seconds from now [or 0]): " + expiry_time + print "Expiry time (seconds from now [or 0]): " + str(expiry_time) rc = XenoUtil.vd_refresh(id, expiry_time) elif cmd == 'list': + print 'ID Size(MB) Expiry' for vbd in XenoUtil.vd_list(): - print """ID: %s -Expires: %s -Expiry time: %s -Size (MB): %d -""" % (vbd['vdisk_id'], vbd['expires'], - str(vbd['expiry_time']), vbd['size'] / 2048) + vbd['size_mb'] = vbd['size'] / 2048 + vbd['expiry'] = (vbd['expires'] and vbd['expiry_time']) or 'never' + print '%(vdisk_id)-4s %(size_mb)-12d %(expiry)s' % vbd elif cmd == 'freespace': diff --git a/tools/xc/lib/xc_netbsd_build.c b/tools/xc/lib/xc_netbsd_build.c index 5736ca5826..f971546ef4 100644 --- a/tools/xc/lib/xc_netbsd_build.c +++ b/tools/xc/lib/xc_netbsd_build.c @@ -389,16 +389,19 @@ myseek(gzFile gfd, off_t offset, int whence) unsigned char tmp[MYSEEK_BUFSIZE]; int c; - if (offset < 0) { + if ( offset < 0 ) + { ERROR("seek back not supported"); return -1; } - while (offset) { + while ( offset != 0 ) + { c = offset; - if (c > MYSEEK_BUFSIZE) + if ( c > MYSEEK_BUFSIZE ) c = MYSEEK_BUFSIZE; - if (gzread(gfd, tmp, c) != c) { + if ( gzread(gfd, tmp, c) != c ) + { PERROR("Error seeking in image."); return -1; } @@ -459,77 +462,91 @@ loadelfimage(gzFile kernel_gfd, int pm_handle, unsigned long *page_array, p = NULL; maxva = 0; - if (gzread(kernel_gfd, &ehdr, sizeof(Elf_Ehdr)) != sizeof(Elf_Ehdr)) { + if ( gzread(kernel_gfd, &ehdr, sizeof(Elf_Ehdr)) != sizeof(Elf_Ehdr) ) + { PERROR("Error reading kernel image ELF header."); goto out; } curpos = sizeof(Elf_Ehdr); - if (!IS_ELF(ehdr)) { + if ( !IS_ELF(ehdr) ) + { PERROR("Image does not have an ELF header."); goto out; } *virt_load_addr = ehdr.e_entry; - if ((*virt_load_addr & (PAGE_SIZE-1)) != 0) { + if ( (*virt_load_addr & (PAGE_SIZE-1)) != 0 ) + { ERROR("We can only deal with page-aligned load addresses"); goto out; } - if ((*virt_load_addr + (tot_pages << PAGE_SHIFT)) > - HYPERVISOR_VIRT_START) { + if ( (*virt_load_addr + (tot_pages << PAGE_SHIFT)) > + HYPERVISOR_VIRT_START ) + { ERROR("Cannot map all domain memory without hitting Xen space"); goto out; } phdr = malloc(ehdr.e_phnum * sizeof(Elf_Phdr)); - if (phdr == NULL) { + if ( phdr == NULL ) + { ERROR("Cannot allocate memory for Elf_Phdrs"); goto out; } - if (myseek(kernel_gfd, ehdr.e_phoff - curpos, SEEK_SET) == -1) { + if ( myseek(kernel_gfd, ehdr.e_phoff - curpos, SEEK_SET) == -1 ) + { ERROR("Seek to program header failed"); goto out; } curpos = ehdr.e_phoff; - if (gzread(kernel_gfd, phdr, ehdr.e_phnum * sizeof(Elf_Phdr)) != - ehdr.e_phnum * sizeof(Elf_Phdr)) { + if ( gzread(kernel_gfd, phdr, ehdr.e_phnum * sizeof(Elf_Phdr)) != + ehdr.e_phnum * sizeof(Elf_Phdr) ) + { PERROR("Error reading kernel image ELF program header."); goto out; } curpos += ehdr.e_phnum * sizeof(Elf_Phdr); - /* Copy kernel .text .data .bss segments into physical memory */ - for (h = 0; h < ehdr.e_phnum; h++) { - if (phdr[h].p_type != PT_LOAD || - (phdr[h].p_flags & (PF_W|PF_X)) == 0) + /* Copy run-time 'load' segments that are writeable and/or executable. */ + for ( h = 0; h < ehdr.e_phnum; h++ ) + { + if ( (phdr[h].p_type != PT_LOAD) || + ((phdr[h].p_flags & (PF_W|PF_X)) == 0) ) continue; - if (IS_TEXT(phdr[h]) || IS_DATA(phdr[h])) { - if (myseek(kernel_gfd, phdr[h].p_offset - curpos, SEEK_SET) == - -1) { + if ( IS_TEXT(phdr[h]) || IS_DATA(phdr[h]) ) + { + if ( myseek(kernel_gfd, phdr[h].p_offset - curpos, + SEEK_SET) == -1 ) + { ERROR("Seek to section failed"); goto out; } curpos = phdr[h].p_offset; - for (iva = phdr[h].p_vaddr; - iva < phdr[h].p_vaddr + phdr[h].p_filesz; iva += c) { + for ( iva = phdr[h].p_vaddr; + iva < phdr[h].p_vaddr + phdr[h].p_filesz; + iva += c) + { c = PAGE_SIZE - (iva & (PAGE_SIZE - 1)); if (iva + c > phdr[h].p_vaddr + phdr[h].p_filesz) c = phdr[h].p_vaddr + phdr[h].p_filesz - iva; - if (gzread(kernel_gfd, page, c) != c) { + if ( gzread(kernel_gfd, page, c) != c ) + { PERROR("Error reading kernel image page."); goto out; } curpos += c; vaddr = map_pfn(pm_handle, page_array[(iva - *virt_load_addr) >> PAGE_SHIFT]); - if (vaddr == NULL) { + if ( vaddr == NULL ) + { ERROR("Couldn't map guest memory"); goto out; } @@ -539,11 +556,12 @@ loadelfimage(gzFile kernel_gfd, int pm_handle, unsigned long *page_array, unmap_pfn(pm_handle, vaddr); } - if (phdr[h].p_vaddr + phdr[h].p_filesz > maxva) + if ( phdr[h].p_vaddr + phdr[h].p_filesz > maxva ) maxva = phdr[h].p_vaddr + phdr[h].p_filesz; } - if (IS_BSS(phdr[h])) { + if ( IS_BSS(phdr[h]) ) + { /* XXX maybe clear phdr[h].p_memsz bytes from phdr[h].p_vaddr + phdr[h].p_filesz ??? */ if (phdr[h].p_vaddr + phdr[h].p_memsz > maxva) @@ -557,21 +575,24 @@ loadelfimage(gzFile kernel_gfd, int pm_handle, unsigned long *page_array, p = malloc(sizeof(int) + sizeof(Elf_Ehdr) + ehdr.e_shnum * sizeof(Elf_Shdr)); - if (p == NULL) { + if ( p == NULL ) + { ERROR("Cannot allocate memory for Elf_Shdrs"); goto out; } shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr)); - if (myseek(kernel_gfd, ehdr.e_shoff - curpos, SEEK_SET) == -1) { + if ( myseek(kernel_gfd, ehdr.e_shoff - curpos, SEEK_SET) == -1 ) + { ERROR("Seek to symbol header failed"); goto out; } curpos = ehdr.e_shoff; - if (gzread(kernel_gfd, shdr, ehdr.e_shnum * sizeof(Elf_Shdr)) != - ehdr.e_shnum * sizeof(Elf_Shdr)) { + if ( gzread(kernel_gfd, shdr, ehdr.e_shnum * sizeof(Elf_Shdr)) != + ehdr.e_shnum * sizeof(Elf_Shdr) ) + { PERROR("Error reading kernel image ELF symbol header."); goto out; } @@ -586,35 +607,45 @@ loadelfimage(gzFile kernel_gfd, int pm_handle, unsigned long *page_array, maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1); /* Copy kernel string / symbol tables into physical memory */ - for (h = 0; h < ehdr.e_shnum; h++) { - if (shdr[h].sh_type == SHT_STRTAB) { - for (i = 0; i < ehdr.e_shnum; i++) - if (shdr[i].sh_type == SHT_SYMTAB && - shdr[i].sh_link == h) + for ( h = 0; h < ehdr.e_shnum; h++ ) + { + if ( shdr[h].sh_type == SHT_STRTAB ) + { + /* Look for a strtab @i linked to symtab @h. */ + for ( i = 0; i < ehdr.e_shnum; i++ ) + if ( (shdr[i].sh_type == SHT_SYMTAB) && + (shdr[i].sh_link == h) ) break; - if (i == ehdr.e_shnum) { + /* Skip symtab @h if we found no corresponding strtab @i. */ + if ( i == ehdr.e_shnum ) + { shdr[h].sh_offset = 0; - continue; /* Skip string tables which are not for symbol tables */ + continue; } } - if (shdr[h].sh_type == SHT_STRTAB || - shdr[h].sh_type == SHT_SYMTAB) { - if (myseek(kernel_gfd, shdr[h].sh_offset - curpos, SEEK_SET) == - -1) { + if ( (shdr[h].sh_type == SHT_STRTAB) || + (shdr[h].sh_type == SHT_SYMTAB) ) + { + if ( myseek(kernel_gfd, shdr[h].sh_offset - curpos, + SEEK_SET) == -1 ) + { ERROR("Seek to symbol section failed"); goto out; } curpos = shdr[h].sh_offset; - shdr[h].sh_offset = maxva - *symtab_addr; /* Mangled to be based on ELF header location */ + /* Mangled to be based on ELF header location. */ + shdr[h].sh_offset = maxva - *symtab_addr; DPRINTF(("copy section %d, size 0x%x\n", h, shdr[h].sh_size)); - for (i = 0; i < shdr[h].sh_size; i += c, maxva += c) { + for ( i = 0; i < shdr[h].sh_size; i += c, maxva += c ) + { c = PAGE_SIZE - (maxva & (PAGE_SIZE - 1)); - if (c > (shdr[h].sh_size - i)) + if ( c > (shdr[h].sh_size - i) ) c = shdr[h].sh_size - i; - if (gzread(kernel_gfd, page, c) != c) { + if ( gzread(kernel_gfd, page, c) != c ) + { PERROR("Error reading kernel image page."); goto out; } @@ -622,7 +653,8 @@ loadelfimage(gzFile kernel_gfd, int pm_handle, unsigned long *page_array, vaddr = map_pfn(pm_handle, page_array[(maxva - *virt_load_addr) >> PAGE_SHIFT]); - if (vaddr == NULL) { + if ( vaddr == NULL ) + { ERROR("Couldn't map guest memory"); goto out; } @@ -636,10 +668,11 @@ loadelfimage(gzFile kernel_gfd, int pm_handle, unsigned long *page_array, maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1); } - shdr[h].sh_name = 0; /* Name is NULL */ + shdr[h].sh_name = 0; /* Name is NULL. */ } - if (*symtab_len == 0) { + if ( *symtab_len == 0 ) + { DPRINTF(("no symbol table\n")); *symtab_addr = 0; ret = 0; @@ -659,13 +692,15 @@ loadelfimage(gzFile kernel_gfd, int pm_handle, unsigned long *page_array, /* Copy total length, crafted ELF header and section header table */ s = sizeof(int) + sizeof(Elf_Ehdr) + ehdr.e_shnum * sizeof(Elf_Shdr); - for (i = 0; i < s; i += c, symva += c) { + for ( i = 0; i < s; i += c, symva += c ) + { c = PAGE_SIZE - (symva & (PAGE_SIZE - 1)); - if (c > s - i) + if ( c > s - i ) c = s - i; vaddr = map_pfn(pm_handle, page_array[(symva - *virt_load_addr) >> PAGE_SHIFT]); - if (vaddr == NULL) { + if ( vaddr == NULL ) + { ERROR("Couldn't map guest memory"); goto out; } @@ -681,7 +716,8 @@ loadelfimage(gzFile kernel_gfd, int pm_handle, unsigned long *page_array, ret = 0; out: - if (ret == 0) { + if ( ret == 0 ) + { maxva = (maxva + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); *ksize = (maxva - *virt_load_addr) >> PAGE_SHIFT; @@ -690,9 +726,9 @@ loadelfimage(gzFile kernel_gfd, int pm_handle, unsigned long *page_array, (void *)*symtab_len)); } - if (phdr) + if ( phdr != NULL ) free(phdr); - if (p) + if ( p != NULL ) free(p); return ret; } -- 2.30.2